package com.ip.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.ip.common.utils.RandomValidateCodeUtil;
import com.ip.db.utils.RedisUtil;
import com.ip.user.models.dto.SliderCaptchaDTO;
import com.ip.user.models.service.SliderCaptchaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 滑块验证码服务实现类
 */
@Service
public class SliderCaptchaServiceImpl implements SliderCaptchaService {

    @Autowired
    private RedisUtil redisUtil;

    // 验证码在Redis中的前缀
    private static final String CAPTCHA_PREFIX = "slider_captcha:";

    // 验证码有效期（分钟）
    private static final long CAPTCHA_EXPIRE_MINUTES = 5;

    @Override
    public Map<String, Object> generateCaptcha() {
        try {
            // 调用无参 createImage()，由工具类决定使用默认图片或类路径图片
            HashMap<String, Object> captchaData = RandomValidateCodeUtil.createImage();

            // 检查是否成功生成验证码
            if (captchaData == null || captchaData.isEmpty() || captchaData.containsKey("error")) {
                Map<String, Object> errorResult = new HashMap<>();
                errorResult.put("success", false);
                errorResult.put("message", captchaData == null ? "生成验证码失败" : captchaData.getOrDefault("error", "生成验证码失败"));
                return errorResult;
            }

            // 检查必要字段是否存在
            if (!captchaData.containsKey("bigImage") || !captchaData.containsKey("smallImage")
                    || !captchaData.containsKey("xWidth") || !captchaData.containsKey("yHeight")) {
                Map<String, Object> errorResult = new HashMap<>();
                errorResult.put("success", false);
                errorResult.put("message", "生成验证码失败，缺少必要字段");
                return errorResult;
            }

            // 生成唯一标识token
            String token = UUID.randomUUID().toString();

            // 存储验证码信息到Redis
            Map<String, Object> captchaInfo = new HashMap<>();
            captchaInfo.put("xWidth", captchaData.get("xWidth"));       // 原始X坐标
            captchaInfo.put("yHeight", captchaData.get("yHeight"));     // 原始Y坐标
            captchaInfo.put("imageWidth", captchaData.get("imageWidth")); // 原图宽度
            captchaInfo.put("imageHeight", captchaData.get("imageHeight")); // 原图高度
            captchaInfo.put("createTime", System.currentTimeMillis());   // 创建时间（用于超时验证）

            // 存入Redis并设置过期时间
            String captchaInfoJson = JSON.toJSONString(captchaInfo);
            redisUtil.set(CAPTCHA_PREFIX + token, captchaInfoJson, CAPTCHA_EXPIRE_MINUTES, TimeUnit.MINUTES);

            // 构造返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("token", token);
            result.put("bigImage", captchaData.get("bigImage"));
            result.put("smallImage", captchaData.get("smallImage"));
            result.put("imageWidth", captchaData.get("imageWidth"));
            result.put("imageHeight", captchaData.get("imageHeight"));

            return result;
        } catch (Exception e) {
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("success", false);
            errorResult.put("message", "生成验证码失败: " + e.getMessage());
            return errorResult;
        }
    }

    @Override
    public boolean verifyCaptcha(SliderCaptchaDTO sliderCaptchaDTO) {
        try {
            String token = sliderCaptchaDTO.getToken();
            double xWidth = sliderCaptchaDTO.getxWidth();
            double yHeight = sliderCaptchaDTO.getyHeight();

            // 检查参数有效性
            if (token == null || token.isEmpty()) {
                return false;
            }

            // 从Redis中获取验证码信息
            String captchaInfoJson = (String) redisUtil.get(CAPTCHA_PREFIX + token);
            if (captchaInfoJson == null || captchaInfoJson.isEmpty()) {
                return false; // 验证码不存在或已过期
            }

            // 解析验证码信息
            Map<String, Object> captchaInfo = JSON.parseObject(captchaInfoJson, Map.class);

            // 检查必要字段
            if (!captchaInfo.containsKey("xWidth") || !captchaInfo.containsKey("yHeight")
                    || !captchaInfo.containsKey("createTime")) {
                return false;
            }

            // 获取原始坐标和创建时间
            double originalX = ((Number) captchaInfo.get("xWidth")).doubleValue();
            double originalY = ((Number) captchaInfo.get("yHeight")).doubleValue();
            long createTime = ((Number) captchaInfo.get("createTime")).longValue();

            // 验证是否超时
            if (System.currentTimeMillis() - createTime > CAPTCHA_EXPIRE_MINUTES * 60 * 1000) {
                redisUtil.del(CAPTCHA_PREFIX + token); // 清理过期数据
                return false;
            }

            // 验证坐标（允许±5像素误差）
            double tolerance = 5.0;
            boolean xValid = Math.abs(xWidth - originalX) <= tolerance;
            boolean yValid = Math.abs(yHeight - originalY) <= tolerance;

            // 验证成功后删除验证码，防止重复使用
            if (xValid && yValid) {
                redisUtil.del(CAPTCHA_PREFIX + token);
                return true;
            }

            return false;
        } catch (Exception e) {
            return false;
        }
    }
}